<?php
declare(strict_types=1);

namespace App\Auth;

use Qbhy\SimpleJwt\Exceptions\TokenBlacklistException;
use Qbhy\SimpleJwt\Exceptions\TokenExpiredException;
use Qbhy\SimpleJwt\Exceptions\TokenNotActiveException;
use Qbhy\SimpleJwt\JWT;
use Qbhy\SimpleJwt\JWTManager;

class AdminJWTManager extends JWTManager
{
    public function parse(string $token): JWT
    {
        $jwt = $this->justParse($token);
        $timestamp = time();
        $payload = $jwt->getPayload();
        $is_credible = $payload['is_credible'] ?? false;

        if ($this->hasBlacklist($jwt)) {
            throw (new TokenBlacklistException('The token is already on the blacklist'))->setJwt($jwt);
        }

        if (!$is_credible && isset($payload['exp']) && $payload['exp'] <= $timestamp) {
            throw (new TokenExpiredException('Token expired'))->setJwt($jwt);
        }

        if (isset($payload['nbf']) && $payload['nbf'] > $timestamp) {
            throw (new TokenNotActiveException('Token not active'))->setJwt($jwt);
        }

        return $jwt;
    }

    public function addBlacklist($jwt)
    {
        $now = time();
        if ($jwt instanceof JWT && ($jwt->getPayload()['is_credible'] ?? false)) {
            // 长期的token，黑名单不过期
            $lifeTime = 0;
        } else {
            // 存到该 token 超过 refresh 即可
            $lifeTime = ($jwt instanceof JWT ? ($jwt->getPayload()['iat'] || $now) : $now) + $this->getRefreshTtl();
        }

        $this->getCache()->save(
            $this->blacklistKey($jwt),
            $now,
            $lifeTime
        );
    }
}
